<?php

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/2/27 0027
 * Time: 22:52
 */
class Pipe
{
    public $fifoPath;
    private $w_pipe;
    private $r_pipe;

    /**
     * classDemo constructor.
     * @param string $name 管道的名称
     * @param int $mode 管道的权限  默认情况下所有用户都可以读写
     * @description:自动创建管道
     */
    public function __construct($name = 'pipeName', $mode = 0666)
    {
//        $fifoPath=posix_getppid();   //posix_getpid 取得当前服务器进程号 此函数只有在Linux下有效 在windows下可以使用get_current_user()。
        if (function_exists('posix_getppid')) {
//            $fifoPath = posix_getppid();
            $fifoPath = "/tmp/$name." . posix_getppid();
//            echo $fifoPath;
            if (!file_exists($fifoPath)) {
                if (!posix_mkfifo($fifoPath, $mode)) {
                    echo "创建{$fifoPath}文件失败";
                    return false;
                }
            } else {
                echo "{$fifoPath}已经存在";
//                return false;
            }
            $this->fifoPath = $fifoPath;

        } else {
//            $fifoPath=get_current_user();  //获取当前 PHP 脚本所有者名称
            $fifoPath = "/tmp/$name." . getmypid();//— 获取 PHP 进程的 ID
//            echo $fifoPath;
            if (!file_exists($fifoPath)) {
                if (!posix_mkfifo($fifoPath, $mode)) {   //posix_mkfifo  创建一个fifo特殊文件(一个命名管道)   (fifo 先进先出  first in，first out)
                    echo "创建{$fifoPath}文件失败";
                    return false;
                }
            } else {
                echo "{$fifoPath}已经存在";
                return false;
            }
            $this->fifoPath = $fifoPath;
        }
    }

    /**
     * @return bool
     * @User: yfl
     * @Time:二〇一七年九月一日 11:06:38
     * @description:写管道开始 打开文件
     */
    public function open_write()
    {
//        var_dump($this->fifoPath);die;
        $this->w_pipe = fopen($this->fifoPath, 'w');
        if ($this->w_pipe == null) {
            echo "open pipe{$this->fifoPath} for write fail";
            return false;
        }
        return true;
    }

    /**
     * @param $data
     * @return bool|int
     * @User: yfl
     * @Time: 二〇一七年九月一日 11:09:11
     * @description: 写入数据
     */
    public function write($data)
    {
        return fwrite($this->w_pipe, $data);
    }

    //写入全部数据
    public function write_all($data)
    {
        $w_pipe = fopen($this->fifoPath, 'w');
        fwrite($w_pipe, $data);
        fclose($w_pipe);
    }

    /**
     * @return bool
     * @User: yfl
     * @Time: 二〇一七年九月一日 11:13:22
     * @description: 关闭资源
     */
    public function close_write()
    {
        return fclose($this->w_pipe);
    }


    //读管道开始
    public function open_read()
    {
        $this->r_pipe = fopen($this->fifoPath, 'r');
        if ($this->r_pipe == null) {
            die("open pipe {$this->fifoPath} for read error.");
            return false;
        }
        return true;
    }

    /**
     * @param int $byte
     * @return bool|string
     * @User: yfl
     * @Time:二〇一七年九月一日 11:18:05
     * @description: 读取管道数据 一次读取1024字节
     */
    public function read($byte = 1024)
    {
        return fread($this->r_pipe, $byte);
    }

    /**
     * @return string
     * @User: yfl
     * @Time:2017年9月1日 11:21:40
     * @description:读取管道文件的所有数据
     */
    public function read_all()
    {
        $r_pipe = fopen($this->fifoPath, 'r');
        $data = '';
        while (!feof($r_pipe)) {
            $data .= fread($r_pipe, 1024);
        }
        fclose($r_pipe);
        return $data;
    }

    /**
     * @return bool
     * @User: yfl
     * @Time:
     * @description:关闭资源
     */
    public function close_read()
    {
        return fclose($this->r_pipe);
    }

    /**
     * @return bool
     * @User: yfl
     * @Time: 2017年9月1日 11:24:03
     * @description: 删除管道
     */
    public function rm_pipe()
    {
        return unlink($this->fifoPath);
    }
}

$obj = new Pipe();
$obj->open_write();
$obj->write('123');
echo $obj->read();
$obj->close_read();
$obj->rm_pipe();